{
  "cells": [
    {
      "metadata": {
        "trusted": true
      },
      "cell_type": "code",
      "source": "# 导入模型资产\nfrom bexk_da_sdk import bexk_da_repo\n# 强制删除旧的模型目录，确保使用全新的训练逻辑\nif os.path.exists(\"./saved_model\"):\n    import shutil\n    if os.path.islink(path):\n        os.unlink(path) # 删除符号链接\n    else:\n        shutil.rmtree(path) # 删除普通目录\n    print(\"已删除旧的模型目录，将重新训练模型\")\npath = \"./saved_model\"\n# bexk_da_repo.load(da_sub_type=\"MD:0T\", da_ename=\"MD_AB_AB_702217\", version=\"1.0.0\", plugins=\"bezk_dir_loader\", target_da_path=path)\nbexk_da_repo.load(\"MD:OT\", \"MD_AC_AC_702217\",path, plugins=\"bexk_dir_loader\")\n\n\n# 检查所在路径\nimport os\nprint(\"当前路径:\", path)\nprint(os.listdir(path))",
      "execution_count": 36,
      "outputs": [
        {
          "output_type": "stream",
          "text": "已删除旧的模型目录，将重新训练模型\n当前路径: ./saved_model\n['meta.json.lock', 'meta.json', 'model', 'metrics.json.lock', 'metrics.json']\n",
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "trusted": true
      },
      "cell_type": "code",
      "source": "!ls ./saved_model/model/task/saved_model",
      "execution_count": 39,
      "outputs": [
        {
          "output_type": "stream",
          "text": "best_model_GradientBoostingRegressor.pkl\r\nbest_model_GradientBoostingRegressor.pkl.lock\r\n",
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "trusted": true
      },
      "cell_type": "code",
      "source": "import os\nimport logging\nimport pandas as pd\nimport numpy as np\nfrom sklearn.model_selection import train_test_split, GridSearchCV\nfrom sklearn.linear_model import LinearRegression, Ridge, Lasso\nfrom sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor\nfrom sklearn.tree import DecisionTreeRegressor\nfrom sklearn.preprocessing import StandardScaler, PolynomialFeatures\nfrom sklearn.feature_selection import SelectKBest, f_regression\nfrom sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error\nimport joblib\n\ndef predict_with_best_model(model_dir, X):\n    \"\"\"使用训练好的最优模型进行预测\"\"\"\n    # 加载模型和特征工程组件\n    # 找到最佳模型文件\n    model_files = [f for f in os.listdir(model_dir+\"/model/task/saved_model\") if f.startswith(\"best_model_\") and f.endswith(\".pkl\")]\n    if not model_files:\n        raise FileNotFoundError(\"未找到训练好的最佳模型\")\n\n    model_path = os.path.join(model_dir+\"/model/task/saved_model\", model_files[0])\n    fe_path = os.path.join(model_dir+\"/model\", \"feature_engineering_objects.pkl\")\n\n    best_model = joblib.load(model_path)\n    fe_objects = joblib.load(fe_path)\n\n    print(f\"成功加载模型: {model_path}\")\n    print(f\"模型期望特征数量: {best_model.n_features_in_}\")\n    print(f\"训练时选择的特征: {fe_objects['selected_features']}\")\n    print(f\"特征数量: {len(fe_objects['selected_features'])}\")\n\n    X_new =  pd.DataFrame(X)\n\n    # 验证输入数据的特征列是否完整\n    required_features = fe_objects['original_feature_columns']\n    missing_features = [col for col in required_features if col not in X_new.columns]\n    if missing_features:\n        raise ValueError(f\"输入数据缺少必要的原始特征: {missing_features}\")\n\n    # 特征处理（与训练时保持完全一致）\n    # 1. 标准化\n    X_scaled = fe_objects['scaler'].transform(X_new[required_features])\n    X_scaled_df = pd.DataFrame(X_scaled, columns=required_features, index=X_new.index)\n\n    # 2. 生成交互特征（如果训练时生成了的话）\n    X_engineered = X_scaled_df.copy()\n    if fe_objects['poly'] is not None and len(fe_objects['interaction_feature_names']) > 0:\n        interaction_features = fe_objects['poly'].transform(X_scaled_df[fe_objects['interaction_features_list']])\n        interaction_feature_names = fe_objects['interaction_feature_names']\n        interaction_df = pd.DataFrame(interaction_features, columns=interaction_feature_names, index=X_new.index)\n\n        # 组合特征\n        X_engineered = pd.concat([X_engineered, interaction_df], axis=1)\n        print(f\"生成交互特征数量: {len(interaction_feature_names)}\")\n\n    print(f\"特征工程后总特征数量: {X_engineered.shape[1]}\")\n\n    # 3. 严格按照训练时选择的特征列表筛选\n    selected_features = fe_objects['selected_features']\n    missing_selected = [col for col in selected_features if col not in X_engineered.columns]\n\n    if missing_selected:\n        raise ValueError(f\"生成的特征中缺少训练时选择的特征: {missing_selected}\")\n\n    X_selected = X_engineered[selected_features]\n    print(f\"筛选后特征数量: {X_selected.shape[1]}\")\n\n    # 验证特征数量是否匹配\n    if X_selected.shape[1] != best_model.n_features_in_:\n        raise ValueError(f\"特征数量不匹配 - 提供: {X_selected.shape[1]}, 期望: {best_model.n_features_in_}\")\n\n    # 预测\n    y_pred = model.predict(X_selected)\n    print(f\"预测完成，生成 {len(y_pred)} 个预测结果\")\n\n    return y_pred\n",
      "execution_count": 47,
      "outputs": []
    },
    {
      "metadata": {
        "trusted": true
      },
      "cell_type": "code",
      "source": "# 预测示例 - 使用用户提供的真实数据样本\nprint(\"\\n\" + \"=\"*80)\nprint(\"预测示例（基于真实数据样本）\")\nprint(\"=\"*80)\n\n\nX_new = {\n    \"MEDINC\": [2.3886],\n    \"HOUSE_AGE\": [16.0],\n    \"AVE_ROOMS\": [5.254716981132075],\n    \"AVE_BEDRMS\": [1.1622641509433962],\n    \"AVE_OCCUP\": [2.616981132075472],\n    \"LATITUDE\": [39.37],\n    \"LONGITUDE\": [-121.24],\n    \"POPULATION\": [1387.0]\n}\n\n# 显示输入特征\nprint(\"输入预测样本特征:\")\nprint(X_new)\nprint()\n\n# 执行预测\npredictions = predict_with_best_model(path, X_new)\n\nprint(predictions)\n",
      "execution_count": 51,
      "outputs": [
        {
          "output_type": "stream",
          "text": "\n================================================================================\n预测示例（基于真实数据样本）\n================================================================================\n输入预测样本特征:\n{'MEDINC': [2.3886], 'HOUSE_AGE': [16.0], 'AVE_ROOMS': [5.254716981132075], 'AVE_BEDRMS': [1.1622641509433962], 'AVE_OCCUP': [2.616981132075472], 'LATITUDE': [39.37], 'LONGITUDE': [-121.24], 'POPULATION': [1387.0]}\n\n成功加载模型: ./saved_model/model/task/saved_model/best_model_GradientBoostingRegressor.pkl\n模型期望特征数量: 10\n训练时选择的特征: Index(['MEDINC', 'HOUSE_AGE', 'AVE_ROOMS', 'AVE_BEDRMS', 'AVE_OCCUP',\n       'LATITUDE', 'inter_0', 'inter_1', 'inter_3', 'inter_4'],\n      dtype='object')\n特征数量: 10\n生成交互特征数量: 6\n特征工程后总特征数量: 14\n筛选后特征数量: 10\n预测完成，生成 1 个预测结果\n[1.02349264]\n",
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "trusted": true
      },
      "cell_type": "code",
      "source": "",
      "execution_count": null,
      "outputs": []
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "name": "python",
      "version": "3.6.5",
      "mimetype": "text/x-python",
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "pygments_lexer": "ipython3",
      "nbconvert_exporter": "python",
      "file_extension": ".py"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}